package edu.mercer.sse.ldap;

import edu.mercer.sse.annotations.Fulfills;
import edu.mercer.sse.app.Config;

import java.security.GeneralSecurityException;
import java.sql.SQLException;
import java.util.Map;

import com.google.common.base.Function;
import com.unboundid.ldap.sdk.LDAPException;

import edu.mercer.sse.database.DB2LDAPLayout;
import edu.mercer.sse.errors.CriticalException;
import edu.mercer.sse.errors.ErrorLoggingVisitor;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;

/**
 * 
 * Delete entry from LDAP.<p>
 *
 * For use with corresponding Predicate showing entries requiring deletion.<p>
 *
 * Returns Boolean for result of LDAP deletion.<p>
 *
 * @see LDAPDeletePredicate
 * 
 * @see Function
 */

public class LDAPDeleteFunction implements 
		
		Function<Map<String, String>, Boolean>
{
	final static String UID_KEY = Config.settings().getProperty(
			"ldap-member-id");

	/** 
	 * No-arg constructor.<p>
	 * 
	 * Delete entry from LDAP.<p>
	 *
	 * For use with corresponding Predicate showing entries requiring deletion.<p>
	 *
	 * Returns Boolean for result of LDAP deletion.<p>
	 *
	 * @see Function
	 * 
	 * @see LDAPDeletePredicate
	 */
	
	public LDAPDeleteFunction(){}
	
	
	@Override
	public Boolean apply( final Map<String, String> entryToDelete )
	{			
		Boolean result = false;
		
		try
		{		
			checkNotNull( UID_KEY, "uid key in configuration is null" );

			checkArgument( UID_KEY.length() > 0, "uid key in configuration "
					+ "is empty" );

			/* 
			 * determine if incoming entry uses ldap keys or database column 
			 * names 
			 */

			String uidValue = "";

			if( entryToDelete.containsKey(UID_KEY) )
			{ 
				uidValue = entryToDelete.get( UID_KEY );

			}
			else if( entryToDelete.containsKey( DB2LDAPLayout.ldapKeyAsdbCol( 
					UID_KEY )))
			{ 
				uidValue = entryToDelete.get( DB2LDAPLayout.ldapKeyAsdbCol( 
						UID_KEY ));

			}//if

			checkArgument( uidValue.length() > 0, "no ldap " + UID_KEY 
					+ " in entry" );

			/* get user dn */

			final String entryDn = "uid=" + uidValue 
					+ ","
					+ Config.settings().getProperty("ldap-entries-ou")
					+ "," 
					+ Config.settings().getProperty("ldap-base-dn");

			checkArgument( LDAPUtility.isPresent(entryDn) , 
					"entry dn incorrect, not exist in ldap: " + entryDn );

			result = LDAPUtility.deleteEntry( entryDn );
			
		}
		catch( final SQLException  | 
					 LDAPException | 
					 GeneralSecurityException err )
		{
			final CriticalException errWrapped = new CriticalException( err );
			errWrapped.accept( new ErrorLoggingVisitor() );
			
			result = false;
			
		}//try
		
		return result;
	
	}//method

	
	@Fulfills("Object")
	@Override
	public String toString()
	{
		return "Delete";
		
	}//method
	
	
}//class
